#include "pageserialportparemeters.h"
#include "ui_pageserialportparemeters.h"

#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>

PageSerialPortParemeters::PageSerialPortParemeters(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::PageSerialPortParemeters)
{
    ui->setupUi(this);

    this->setAttribute(Qt::WA_DeleteOnClose, true);

    InitLayout();

    ConnectSignalSlot();
}

PageSerialPortParemeters::~PageSerialPortParemeters()
{
    delete ui;

    if (mSerialPortSettings)
    {
        delete mSerialPortSettings;
        mSerialPortSettings = nullptr;
    }
}

void PageSerialPortParemeters::InitLayout()
{
    mSerialPortSettings = new SerialPortSettings();

    InitSerialPortCOM();
    InitSerialPortBadurate();
    InitSerialPortDataBits();
    InitSerialPortParity();
    InitSerialPortStopBits();
    InitSerialPortFlowControl();

    this->mSerialPortSettings->portName     = (0 != ui->comboBox_COM->count()) ? ui->comboBox_COM->currentData().toStringList().first() : "";
    this->mSerialPortSettings->baudrate     = static_cast<QSerialPort::BaudRate>(ui->comboBox_Baudrate->currentData().toInt());
    this->mSerialPortSettings->dataBits     = static_cast<QSerialPort::DataBits>(ui->comboBox_DataBits->currentData().toInt());
    this->mSerialPortSettings->parity       = static_cast<QSerialPort::Parity>(ui->comboBox_Parity->currentData().toInt());
    this->mSerialPortSettings->stopBits     = static_cast<QSerialPort::StopBits>(ui->comboBox_StopBits->currentData().toInt());
    this->mSerialPortSettings->flowControl  = static_cast<QSerialPort::FlowControl>(ui->comboBox_FlowControl->currentData().toInt());
}

void PageSerialPortParemeters::ConnectSignalSlot()
{
    connect(ui->pushButton_RefreshCOM, &QPushButton::clicked, this, [=](){
        ui->comboBox_COM->clear();
        InitSerialPortCOM();
    });

    connect(ui->comboBox_COM, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        QStringList strList = ui->comboBox_COM->currentData().toStringList();
        if (!strList.isEmpty())
        {
            this->mSerialPortSettings->portName = ui->comboBox_COM->currentData().toStringList().first();
        }
    });
    connect(ui->comboBox_Baudrate, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        this->mSerialPortSettings->baudrate = static_cast<QSerialPort::BaudRate>(ui->comboBox_Baudrate->currentData().toInt());
    });
    connect(ui->comboBox_DataBits, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        this->mSerialPortSettings->dataBits = static_cast<QSerialPort::DataBits>(ui->comboBox_DataBits->currentData().toInt());
    });
    connect(ui->comboBox_Parity, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        this->mSerialPortSettings->parity = static_cast<QSerialPort::Parity>(ui->comboBox_Parity->currentData().toInt());
    });
    connect(ui->comboBox_StopBits, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        this->mSerialPortSettings->stopBits = static_cast<QSerialPort::StopBits>(ui->comboBox_StopBits->currentData().toInt());
    });
    connect(ui->comboBox_FlowControl, static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged), this, [=](){
        this->mSerialPortSettings->flowControl = static_cast<QSerialPort::FlowControl>(ui->comboBox_FlowControl->currentData().toInt());
    });

    connect(ui->pushButton_Connect, &QPushButton::clicked, this, [=](){
        emit signalConnectSerialPort(this->mSerialPortSettings);
    });

    connect(ui->pushButton_DisConnect, &QPushButton::clicked, this, &PageSerialPortParemeters::close);
}

void PageSerialPortParemeters::InitSerialPortCOM()
{
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QStringList list;
        list << info.portName() << info.description();
        ui->comboBox_COM->addItem(QString("%1  %2").arg(list.first(), info.description()), list);
    }
}

void PageSerialPortParemeters::InitSerialPortBadurate()
{
    ui->comboBox_Baudrate->addItem(QStringLiteral("2400"), QSerialPort::Baud2400);
    ui->comboBox_Baudrate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
    ui->comboBox_Baudrate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
    ui->comboBox_Baudrate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);

    ui->comboBox_Baudrate->setCurrentIndex(3);
}

void PageSerialPortParemeters::InitSerialPortDataBits()
{
    ui->comboBox_DataBits->addItem(QStringLiteral("5"), QSerialPort::Data5);
    ui->comboBox_DataBits->addItem(QStringLiteral("6"), QSerialPort::Data6);
    ui->comboBox_DataBits->addItem(QStringLiteral("7"), QSerialPort::Data7);
    ui->comboBox_DataBits->addItem(QStringLiteral("8"), QSerialPort::Data8);

    ui->comboBox_DataBits->setCurrentIndex(3);
}

void PageSerialPortParemeters::InitSerialPortParity()
{
    ui->comboBox_Parity->addItem(tr("无校验"), QSerialPort::NoParity);
    ui->comboBox_Parity->addItem(tr("偶校验"), QSerialPort::EvenParity);
    ui->comboBox_Parity->addItem(tr("奇校验"), QSerialPort::OddParity);
    ui->comboBox_Parity->addItem(tr("1校验"), QSerialPort::MarkParity);
    ui->comboBox_Parity->addItem(tr("0校验"), QSerialPort::SpaceParity);
}

void PageSerialPortParemeters::InitSerialPortStopBits()
{
    ui->comboBox_StopBits->addItem(QStringLiteral("1"), QSerialPort::OneStop);
#ifdef Q_OS_WIN
    ui->comboBox_StopBits->addItem(tr("1.5"), QSerialPort::OneAndHalfStop);
#endif
    ui->comboBox_StopBits->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
}

void PageSerialPortParemeters::InitSerialPortFlowControl()
{
    ui->comboBox_FlowControl->addItem(tr("无流控"), QSerialPort::NoFlowControl);
    ui->comboBox_FlowControl->addItem(tr("硬件流控"), QSerialPort::HardwareControl);
    ui->comboBox_FlowControl->addItem(tr("软件流控"), QSerialPort::SoftwareControl);
}

void PageSerialPortParemeters::slotOpenSerialPort(bool retsult, QString COM)
{
    Q_UNUSED(COM)

    if (retsult)
    {
        this->close();
    }
    else
    {
        QMessageBox::information(this, tr("提示"), tr("串口打开失败"));
    }
}
